// hwintypes.h
#pragma once

#ifndef __HWINTYPES_H__
#define __HWINTYPES_H__

#include "hwinstring.h"
#include "hwinexception.h"

namespace harlinn
{
    namespace windows
    {
        enum class UnicodeCategory : char
        {
            // Uppercase letter. Signified by the Unicode designation "Lu" (letter, uppercase).
            UppercaseLetter = 0,
            // Lowercase letter. Signified by the Unicode designation "Ll" (letter, lowercase).
            LowercaseLetter = 1,
            // Titlecase letter. Signified by the Unicode designation "Lt" (letter, titlecase).
            TitlecaseLetter = 2,
            // Modifier letter character, which is free-standing spacing character that
            // indicates modifications of a preceding letter. Signified by the Unicode designation
            // "Lm" (letter, modifier).
            ModifierLetter = 3,
            // Letter that is not an uppercase letter, a lowercase letter, a titlecase letter,
            // or a modifier letter. Signified by the Unicode designation "Lo" (letter,
            // other).
            OtherLetter = 4,
            // Nonspacing character that indicates modifications of a base character. Signified
            // by the Unicode designation "Mn" (mark, nonspacing).
            NonSpacingMark = 5,
            // Spacing character that indicates modifications of a base character and affects
            // the width of the glyph for that base character. Signified by the Unicode
            // designation "Mc" (mark, spacing combining).
            SpacingCombiningMark = 6,
            // Enclosing mark character, which is a nonspacing combining character that
            // surrounds all previous characters up to and including a base character. Signified
            // by the Unicode designation "Me" (mark, enclosing).
            EnclosingMark = 7,
            // Decimal digit character, that is, a character in the range 0 through 9. Signified
            // by the Unicode designation "Nd" (number, decimal digit).
            DecimalDigitNumber = 8,
            // Number represented by a letter, instead of a decimal digit, for example,
            // the Roman numeral for five, which is "V". The indicator is signified by the
            // Unicode designation "Nl" (number, letter).
            LetterNumber = 9,
            // Number that is neither a decimal digit nor a letter number, for example,
            // the fraction 1/2. The indicator is signified by the Unicode designation "No"
            // (number, other).
            OtherNumber = 10,
            // Space character, which has no glyph but is not a control or format character.
            // Signified by the Unicode designation "Zs" (separator, space).
            SpaceSeparator = 11,
            // Character that is used to separate lines of text. Signified by the Unicode
            // designation "Zl" (separator, line).
            LineSeparator = 12,
            // Character used to separate paragraphs. Signified by the Unicode designation
            // "Zp" (separator, paragraph).
            ParagraphSeparator = 13,
            // Control code character, with a Unicode value of U+007F or in the range U+0000
            // through U+001F or U+0080 through U+009F. Signified by the Unicode designation
            // "Cc" (other, control).
            Control = 14,
            // Format character that affects the layout of text or the operation of text
            // processes, but is not normally rendered. Signified by the Unicode designation
            // "Cf" (other, format).
            Format = 15,
            // High surrogate or a low surrogate character. Surrogate code values are in
            // the range U+D800 through U+DFFF. Signified by the Unicode designation "Cs"
            // (other, surrogate).
            Surrogate = 16,
            // Private-use character, with a Unicode value in the range U+E000 through U+F8FF.
            // Signified by the Unicode designation "Co" (other, private use). 
            PrivateUse = 17,
            // Connector punctuation character that connects two characters. Signified by
            // the Unicode designation "Pc" (punctuation, connector).
            ConnectorPunctuation = 18,
            // Dash or hyphen character. Signified by the Unicode designation "Pd" (punctuation,
            // dash).
            DashPunctuation = 19,
            // Opening character of one of the paired punctuation marks, such as parentheses,
            // square brackets, and braces. Signified by the Unicode designation "Ps" (punctuation,
            // open).
            OpenPunctuation = 20,
            // Closing character of one of the paired punctuation marks, such as parentheses,
            // square brackets, and braces. Signified by the Unicode designation "Pe" (punctuation,
            // close).
            ClosePunctuation = 21,
            // Opening or initial quotation mark character. Signified by the Unicode designation
            // "Pi" (punctuation, initial quote).
            InitialQuotePunctuation = 22,
            // Closing or final quotation mark character. Signified by the Unicode designation
            // "Pf" (punctuation, final quote).
            FinalQuotePunctuation = 23,
            // Punctuation character that is not a connector, a dash, open punctuation,
            // close punctuation, an initial quote, or a final quote. Signified by the Unicode
            // designation "Po" (punctuation, other).
            OtherPunctuation = 24,
            // Mathematical symbol character, such as "+" or "= ". Signified by the Unicode
            // designation "Sm" (symbol, math).
            MathSymbol = 25,
            // Currency symbol character. Signified by the Unicode designation "Sc" (symbol,
            // currency).
            CurrencySymbol = 26,
            // Modifier symbol character, which indicates modifications of surrounding characters.
            // For example, the fraction slash indicates that the number to the left is
            // the numerator and the number to the right is the denominator. The indicator
            // is signified by the Unicode designation "Sk" (symbol, modifier).
            ModifierSymbol = 27,
            // Symbol character that is not a mathematical symbol, a currency symbol or
            // a modifier symbol. Signified by the Unicode designation "So" (symbol, other).
            OtherSymbol = 28,
            // Character that is not assigned to any Unicode category. Signified by the
            // Unicode designation "Cn" (other, not assigned). 
            OtherNotAssigned = 29
        };

        class Char
        {
        public:
            typedef Char Type;
            typedef wchar_t ValueType;
            static ValueType MinValue() { return 0; }
            static ValueType MaxValue() { return 0xFFFF; }
        private:
            ValueType value;
        public:
            Char()
                : value(0)
            {}

            Char(ValueType theValue)
                : value(theValue)
            {}

            Char(const Char& theValue)
                : value(theValue.value)
            {}

            Char& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Char& operator = (const Char& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }


            static bool IsLatin1( ValueType ch ) 
            {
                return ch <= 0x00FF;
            }

            bool IsLatin1() const
            {
                return IsLatin1(value);
            }

            static bool IsAscii( ValueType ch ) 
            {
                return ch <= 0x007F;
            }

            bool IsAscii() const
            {
                return IsAscii(value);
            }

            static bool IsHighSurrogate(ValueType c) 
            { 
                return ((c >= HIGH_SURROGATE_START) && (c <= HIGH_SURROGATE_END));
            } 

            bool IsHighSurrogate() const
            {
                return IsHighSurrogate(value);
            }

            static bool IsLowSurrogate(ValueType c) 
            { 
                return ((c >= LOW_SURROGATE_START) && (c <= LOW_SURROGATE_END)); 
            }

            bool IsLowSurrogate() const
            {
                return IsLowSurrogate(value);
            }

            static bool IsControl(ValueType c) 
            {
                return iswcntrl(c) != 0;
            }

            bool IsControl() const
            {
                return IsControl(value);
            }

            static bool IsDigit(ValueType c) 
            {
                return iswdigit(c) != 0;
            }

            bool IsDigit() const
            {
                return IsDigit(value);
            }

            static bool IsLetter(ValueType c) 
            {
                return iswalpha(c) != 0;
            }

            bool IsLetter() const
            {
                return IsLetter(value);
            }

            static bool IsLetterOrDigit(ValueType c) 
            {
                return iswalnum(c) != 0;
            }

            bool IsLetterOrDigit() const
            {
                return IsLetterOrDigit(value);
            }

            static bool IsLower(ValueType c) 
            {
                return iswlower(c) != 0;
            }

            bool IsLower() const
            {
                return IsLower(value);
            }

            static bool IsUpper(ValueType c) 
            {
                return iswupper(c) != 0;
            }

            bool IsUpper() const
            {
                return IsUpper(value);
            }


            static bool IsPunctuation(ValueType c) 
            {
                return iswpunct(c) != 0;
            }

            bool IsPunctuation() const
            {
                return IsPunctuation(value);
            }

            static bool IsWhiteSpace(ValueType c) 
            {
                return iswspace(c) != 0;
            }

            bool IsWhiteSpace() const
            {
                return IsWhiteSpace(value);
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Char& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Char& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Char& result);

            HWIN_EXPORT static Char Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Char Parse(const wchar_t* theText);
            HWIN_EXPORT static Char Parse(const String& theText,size_t theTextLength);


        };

        class Boolean
        {
        public:
            typedef Boolean Type;
            typedef bool ValueType;
            static ValueType MinValue() { return false; }
            static ValueType MaxValue() { return true; }
        private:
            ValueType value;
        public:
            Boolean()
                : value(0)
            {}

            Boolean(ValueType theValue)
                : value(theValue)
            {}

            Boolean(const Boolean& theValue)
                : value(theValue.value)
            {}

            Boolean& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Boolean& operator = (const Boolean& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Boolean& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Boolean& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Boolean& result);

            HWIN_EXPORT static Boolean Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Boolean Parse(const wchar_t* theText);
            HWIN_EXPORT static Boolean Parse(const String& theText,size_t theTextLength);

        };

        class Byte
        {
        public:
            typedef Byte Type;
            typedef unsigned char ValueType;
            static ValueType MinValue() { return 0; }
            static ValueType MaxValue() { return MAXBYTE; }
        private:
            ValueType value;
        public:
            Byte()
                : value(0)
            {}

            Byte(ValueType theValue)
                : value(theValue)
            {}

            Byte(const Byte& theValue)
                : value(theValue.value)
            {}

            Byte& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Byte& operator = (const Byte& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Byte& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Byte& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Byte& result);

            HWIN_EXPORT static Byte Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Byte Parse(const wchar_t* theText);
            HWIN_EXPORT static Byte Parse(const String& theText,size_t theTextLength);


        };

        class SByte
        {
        public:
            typedef SByte Type;
            typedef char ValueType;
            static ValueType MinValue() { return ~MAXCHAR; }
            static ValueType MaxValue() { return MAXCHAR; }
        private:
            ValueType value;
        public:
            SByte()
                : value(0)
            {}

            SByte(ValueType theValue)
                : value(theValue)
            {}

            SByte(const SByte& theValue)
                : value(theValue.value)
            {}

            SByte& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            SByte& operator = (const SByte& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, SByte& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, SByte& result);
            HWIN_EXPORT static bool TryParse(const String& theText, SByte& result);

            HWIN_EXPORT static SByte Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static SByte Parse(const wchar_t* theText);
            HWIN_EXPORT static SByte Parse(const String& theText,size_t theTextLength);

        };

        class Int16
        {
        public:
            typedef Int16 Type;
            typedef short ValueType;
            static ValueType MinValue() { return MININT16; }
            static ValueType MaxValue() { return MAXINT16; }
        private:
            ValueType value;
        public:
            Int16()
                : value(0)
            {}

            Int16(ValueType theValue)
                : value(theValue)
            {}

            Int16(const Int16& theValue)
                : value(theValue.value)
            {}

            Int16& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Int16& operator = (const Int16& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Int16& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Int16& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Int16& result);

            HWIN_EXPORT static Int16 Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Int16 Parse(const wchar_t* theText);
            HWIN_EXPORT static Int16 Parse(const String& theText,size_t theTextLength);

        };

        class UInt16
        {
        public:
            typedef UInt16 Type;
            typedef unsigned short ValueType;
            static ValueType MinValue() { return 0; }
            static ValueType MaxValue() { return MAXUINT16; }
        private:
            ValueType value;
        public:
            UInt16()
                : value(0)
            {}

            UInt16(ValueType theValue)
                : value(theValue)
            {}

            UInt16(const UInt16& theValue)
                : value(theValue.value)
            {}

            UInt16& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            UInt16& operator = (const UInt16& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, UInt16& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, UInt16& result);
            HWIN_EXPORT static bool TryParse(const String& theText, UInt16& result);

            HWIN_EXPORT static UInt16 Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static UInt16 Parse(const wchar_t* theText);
            HWIN_EXPORT static UInt16 Parse(const String& theText,size_t theTextLength);

        };


        class Int32
        {
        public:
            typedef Int32 Type;
            typedef long ValueType;
            static ValueType MinValue() { return MININT32; }
            static ValueType MaxValue() { return MAXINT32; }
        private:
            ValueType value;
        public:
            Int32()
                : value(0)
            {}

            Int32(ValueType theValue)
                : value(theValue)
            {}

            Int32(const Int32& theValue)
                : value(theValue.value)
            {}

            Int32& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Int32& operator = (const Int32& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Int32& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Int32& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Int32& result);

            HWIN_EXPORT static Int32 Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Int32 Parse(const wchar_t* theText);
            HWIN_EXPORT static Int32 Parse(const String& theText,size_t theTextLength);

        };

        class UInt32
        {
        public:
            typedef UInt32 Type;
            typedef unsigned long ValueType;
            static ValueType MinValue() { return 0; }
            static ValueType MaxValue() { return MAXUINT32; }
        private:
            ValueType value;
        public:
            UInt32()
                : value(0)
            {}

            UInt32(ValueType theValue)
                : value(theValue)
            {}

            UInt32(const UInt32& theValue)
                : value(theValue.value)
            {}

            UInt32& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            UInt32& operator = (const UInt32& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, UInt32& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, UInt32& result);
            HWIN_EXPORT static bool TryParse(const String& theText, UInt32& result);

            HWIN_EXPORT static UInt32 Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static UInt32 Parse(const wchar_t* theText);
            HWIN_EXPORT static UInt32 Parse(const String& theText,size_t theTextLength);

        };


        class Int64
        {
        public:
            typedef Int64 Type;
            typedef long long ValueType;
            static ValueType MinValue() { return MININT64; }
            static ValueType MaxValue() { return MAXINT64; }
        private:
            ValueType value;
        public:
            Int64()
                : value(0)
            {}

            Int64(ValueType theValue)
                : value(theValue)
            {}

            Int64(const Int64& theValue)
                : value(theValue.value)
            {}

            Int64& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Int64& operator = (const Int64& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Int64& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Int64& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Int64& result);

            HWIN_EXPORT static Int64 Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Int64 Parse(const wchar_t* theText);
            HWIN_EXPORT static Int64 Parse(const String& theText,size_t theTextLength);

        };

        class UInt64
        {
        public:
            typedef UInt64 Type;
            typedef unsigned long long ValueType;
            static ValueType MinValue() { return 0; }
            static ValueType MaxValue() { return MAXUINT64; }
        private:
            ValueType value;
        public:
            UInt64()
                : value(0)
            {}

            UInt64(ValueType theValue)
                : value(theValue)
            {}

            UInt64(const UInt64& theValue)
                : value(theValue.value)
            {}

            UInt64& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            UInt64& operator = (const UInt64& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, UInt64& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, UInt64& result);
            HWIN_EXPORT static bool TryParse(const String& theText, UInt64& result);

            HWIN_EXPORT static UInt64 Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static UInt64 Parse(const wchar_t* theText);
            HWIN_EXPORT static UInt64 Parse(const String& theText,size_t theTextLength);
        };


        class Single
        {
        public:
            typedef Single Type;
            typedef float ValueType;
            static ValueType MinValue() { return FLT_MIN; }
            static ValueType MaxValue() { return FLT_MAX; }
            static ValueType Epsilon() { return FLT_EPSILON; }
        private:
            ValueType value;
        public:
            Single()
                : value(0.0f)
            {}

            Single(ValueType theValue)
                : value(theValue)
            {}

            Single(const Single& theValue)
                : value(theValue.value)
            {}

            Single& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Single& operator = (const Single& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Single& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Single& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Single& result);

            HWIN_EXPORT static Single Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Single Parse(const wchar_t* theText);
            HWIN_EXPORT static Single Parse(const String& theText,size_t theTextLength);

        };

        class Double
        {
        public:
            typedef Double Type;
            typedef double ValueType;
            static ValueType MinValue() { return DBL_MIN; }
            static ValueType MaxValue() { return DBL_MAX; }
            static ValueType Epsilon() { return DBL_EPSILON; }
        private:
            ValueType value;
        public:
            Double()
                : value(0.0)
            {}

            Double(ValueType theValue)
                : value(theValue)
            {}

            Double(const Double& theValue)
                : value(theValue.value)
            {}

            Double& operator = (ValueType theValue)
            {
                value = theValue;
                return *this;
            }

            Double& operator = (const Double& theValue)
            {
                value = theValue.value;
                return *this;
            }

            operator ValueType() const
            {
                return value;
            }

            HWIN_EXPORT static bool TryParse(const wchar_t* theText,size_t theTextLength, Double& result);
            HWIN_EXPORT static bool TryParse(const wchar_t* theText, Double& result);
            HWIN_EXPORT static bool TryParse(const String& theText, Double& result);

            HWIN_EXPORT static Double Parse(const wchar_t* theText,size_t theTextLength);
            HWIN_EXPORT static Double Parse(const wchar_t* theText);
            HWIN_EXPORT static Double Parse(const String& theText,size_t theTextLength);

        };






    };
};

#endif // __HWINTYPES_H__
